package com.kingyun.gpsinspection.purificationservice.services.jsm.innerservice.impl.reportTemp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqhilink.api.common.utils.UniqueUtil;
import com.cqhilink.api.common.utils.date.DateUtil;
import com.cqhilink.api.common.utils.enums.RespCodeEnum;
import com.kingyun.gpsinspection.purificationservice.common.constant.BackMessage;
import com.kingyun.gpsinspection.purificationservice.common.enums.TreeIconSkinEnum;
import com.kingyun.gpsinspection.purificationservice.common.poi.ReportUtil;
import com.kingyun.gpsinspection.purificationservice.dao.mapper.jsm.*;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.*;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.employee.JsmEmployeeService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.entity.JsmEntityService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.property.JsmEntityPropertyService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.reportTemp.JsmReportTempService;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 报表模板service接口实现类
 * Created by yangcs on 2017/3/9.
 */

public class JsmReportTempServiceImpl implements JsmReportTempService {
    public Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JsmReportTempMapper jsmReportTempMapper;
    @Autowired
    private ReportTempHeadMapper reportTempHeadMapper;
    @Autowired
    private ReportTempTotalMapper reportTempTotalMapper;
    @Autowired
    private JsmEntityService entityService;
    @Autowired
    private JsmReportMapper jsmReportMapper;
    @Autowired
    private JsmEntityPropertyService entityPropertyService;
    @Autowired
    private JsmEmployeeService employeeService;
    @Autowired
    private IntDataSrcItemValueMapper intDataSrcItemValueMapper;
    @Autowired
    private JsmOrganizationMapper jsmOrganizationMapper;

    /**
     * 获取列表数据
     * @param reportTemp
     * @return
     */
    @Override
    public JSONObject list(ReportTemp reportTemp) {
        JSONObject jsonObject = new JSONObject();
        reportTemp.setLimit(reportTemp.getLimit() == null ? 10 : reportTemp.getLimit());
        reportTemp.setOffset(reportTemp.getOffset() == null ? 0 : reportTemp.getOffset());
        jsonObject.put("total", jsmReportTempMapper.queryListCount(reportTemp));
        jsonObject.put("rows", JSON.toJSON(jsmReportTempMapper.queryList(reportTemp)));
        return jsonObject;
    }

    /**
     * 批量删除
     * @param list
     * @return
     */
    @Override
    public Map<String, Object> delRepItem(List<String> list) {
        Map<String, Object> resMap = new HashMap<>();
        if(list!=null){
            for(String itemId : list){
                jsmReportTempMapper.updateStatus(itemId);
            }
            resMap.put("msg", BackMessage.DEL_OK);
            resMap.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
        }else{
            resMap.put("msg",BackMessage.EXCEPTION_ISNULL);
            resMap.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
        }
        return resMap;
    }

    /**
     * 根据组织id查询实体特性
     * @param orgId
     * @return
     */
    @Override
    public List<Ztree> getEntityPorperties(String orgId){
        // 查询组织
        List<Organization> organizations = jsmOrganizationMapper.getOrgPorperties(orgId);
        // 查询设备
        List<EntityVo> list = entityService.getEntityPorperties(orgId);
        // 查询特性值
        // 如果不为空，把entity转换橙Ztree
        List<Ztree> tree = new ArrayList<Ztree>();
        List<String> strs = new ArrayList<>();
        Ztree enTree;

        if( organizations != null && organizations.size() > 0 ){
            for ( Organization organization : organizations ){
                enTree = new Ztree();
                enTree.setId(organization.getOrgId());
                enTree.setName(organization.getOrgName());
                // 父级组织和所选组织相同，第一级
                if( organization.getParentOrgId().equals(orgId) ){
                    enTree.setpId("#");
                }else{
                    // 否则父级为上级组织
                    enTree.setpId(organization.getParentOrgId());
                }
                enTree.setOpen(RespCodeEnum.RESP_CODE_ENUM_false.code());
                // 级别是4是场站
                if( organization.getOrgLevelId().equals("4") ){
                    enTree.setIconSkin(TreeIconSkinEnum.ICON_STATION.getDesc());
                }else{
                    // 级别是5是井
                    enTree.setIconSkin(TreeIconSkinEnum.IONC_WELL.getDesc());
                }
                tree.add(enTree);
                strs.add(organization.getId());
            }
        }
        if( list != null && list.size() > 0 ){
            for (EntityVo entity:list){
                enTree = new Ztree();
                enTree.setId(entity.getEnId());
                enTree.setName(entity.getEnName());
                // 设备组织和所选组织相同 第一级
                if( entity.getParentOrgId().equals(orgId) ){
                    enTree.setpId("#");
                }else{
                    // 否则父级entityId为空时为所属组织，否则为上级entityId
                    enTree.setpId(StringUtils.isBlank(entity.getParentEnId())?entity.getParentOrgId():entity.getParentEnId());
                }
                enTree.setOpen(RespCodeEnum.RESP_CODE_ENUM_false.code());
                enTree.setIconSkin(TreeIconSkinEnum.ICON_ENTITY.getDesc());
                tree.add(enTree);
                strs.add(entity.getEnId());
            }
        }
        // 查询特性值
        if( strs.size() > 0 ){
            List<EntityPro> pros = entityPropertyService.selectByEntityIds(strs,orgId);
            // 特性值不为空时转换为ztree
            if( pros != null && pros.size() > 0 ){
                for( EntityPro pro:pros ){
                    enTree = new Ztree();
                    enTree.setId(pro.getDevicePropertyId());
                    enTree.setName(pro.getPropertyName());
                    enTree.setpId(pro.getEntityId());
                    enTree.setOpen(RespCodeEnum.RESP_CODE_ENUM_false.code());
                    enTree.setIsEntity(0);
                    enTree.setIconSkin(TreeIconSkinEnum.ICON_DEVICE_CHARA.getDesc());
                    tree.add(enTree);
                }
            }
        }
        return tree;
    }

    /**
     * 插入报表模板
     * @param reportTemp
     * @param heads
     * @return
     */
    @Override
    public void saveTemp(ReportTemp reportTemp, List<ReportTempHead> heads,Employee employee) {
        // 当前登录人id
        String userId = employee.getEmployeeId();
        // 新增报表基本信息
        reportTemp.setCreateUserId(userId);
        reportTemp.setModifyUserId(userId);
        reportTemp.setReportTempId(UniqueUtil.uuid());
        int result = jsmReportTempMapper.insert(reportTemp);
        if( result > 0 ){
            // 实例化一张报表
            Report report = new Report();
            report.setReportTempId(reportTemp.getReportTempId());
            report.setOrgId(reportTemp.getOrgId());
            report.setReportId(UniqueUtil.uuid());
            jsmReportTempMapper.insertReport(report);
            saveHeadsAndSums(reportTemp,heads,userId);
        }
    }

    /**
     * 根据id查询模板信息
     * @param reportTempId
     * @return
     */
    @Override
    public ReportTemp queryById(String reportTempId) {
        ReportTemp reportTemp = jsmReportTempMapper.queryById(reportTempId);
        if( StringUtils.isNotBlank(reportTemp.getOrgId()) ){
            List<String> orgs = Arrays.asList(reportTemp.getOrgId().split(","));
            reportTemp.setOrgName( jsmReportTempMapper.queryOrgNames(orgs) );
        }
        return reportTemp;
    }

    /**
     * 根据层级和模板id查询表头
     * @param reportTempId
     * @param level
     * @return
     */
    @Override
    public List<ReportTempHead> queryHeadsByIdAndLevel(String reportTempId, int level) {
        Map map = new HashMap<>();
        map.put("reportTempId",reportTempId);
        map.put("level",level);
        return reportTempHeadMapper.queryHeadsByIdAndLevel(map);
    }

    /**
     * 根据模板id查询合计
     * @param reportTempId
     * @return
     */
    @Override
    public List<ReportTempTotal> queryTotalsById(String reportTempId) {
        return reportTempTotalMapper.queryTotalsById(reportTempId);
    }

    /**
     * 修改模板
     * @param reportTemp
     * @param heads
     */
    @Override
    public void updateTemp(ReportTemp reportTemp, List<ReportTempHead> heads, Employee employee) {
        // 当前登录人id
        String userId = employee.getEmployeeId();
        reportTemp.setModifyUserId(userId);
        int result = jsmReportTempMapper.updateTemp(reportTemp);
        // 修改成功，则先删除原来的表头和合计，再新增表头和合计
        if( result > 0 ){
            reportTempHeadMapper.deleteByTempId(reportTemp.getReportTempId());
            saveHeadsAndSums(reportTemp,heads,userId);
        }
    }

    /**
     * 获取表头
     * @param reportTempId
     * @param reportId
     * @return
     */
    @Override
    public JSONArray getHeads(String reportTempId, String reportId) {
        // 当模板id为空时，根据报表ID查询模板id
        if( StringUtils.isBlank(reportTempId) ){
            reportTempId = jsmReportMapper.selectByPrimaryKey(reportId).getReportTempId();
        }
        return getJsonHead(queryHeadsByIdAndLevel(reportTempId,1));
    }

    /**
     * 将表头集合转成json
     * @param list
     * @return
     */
    @Override
    public JSONArray getJsonHead(List<ReportTempHead> list){
        JSONArray array = new JSONArray();
        JSONObject firstHeadObj;
        JSONObject secondHeadObj;
        JSONArray secondHeadArray;
        List<ReportTempHead> secondHeads;
        String apId;
        if( list != null && list.size() > 0 ){
            for ( ReportTempHead head:list ){
                firstHeadObj = new JSONObject();
                firstHeadObj.put("fieldName",head.getHeadName());
                firstHeadObj.put("unit",head.getUnit());
                // 如果有子节点
                secondHeads = head.getSub();
                // 二级表头不为空时循环
                if( secondHeads != null && secondHeads.size() > 0 ){
                    secondHeadArray = new JSONArray();
                    for ( ReportTempHead  secondHead:secondHeads){
                        secondHeadObj = new JSONObject();
                        secondHeadObj.put("fieldName",secondHead.getHeadName());
                        secondHeadObj.put("unit",secondHead.getUnit());
                        secondHeadObj.put("fieldId",changeApId(secondHead.getApId()));
                        secondHeadArray.add(secondHeadObj);
                    }
                    firstHeadObj.put("subField",secondHeadArray);
                }else{
                    // 没有子节点设置fieldId
                    apId = head.getApId();
                    firstHeadObj.put("fieldId",changeApId(apId));
                }
                array.add(firstHeadObj);
            }
        }
        return array;
    }

    /**
     * 获取合计信息
     * @param reportTempId
     * @param reportId
     * @return
     */
    @Override
    public JSONArray getSums(String reportTempId, String reportId) {
        Report report = jsmReportMapper.selectByPrimaryKey(reportId);
        if( report == null ){
            report = new Report();
            report.setReportTempId(reportTempId);
        }
        return getJsonSums(reportTempTotalMapper.getSums(report),reportId);
    }

    /**
     * 合计集合转json
     * @param totals
     * @param reportId
     * @return
     */
    @Override
    public JSONArray getJsonSums(List<ReportTempTotal> totals,String reportId){
        JSONArray array = new JSONArray();
        JSONObject sumObj;
        // 合计不为空时循环
        if( totals != null && totals.size() > 0 ){
            for( ReportTempTotal total:totals ){
                sumObj = new JSONObject();
                sumObj.put("fieldId",total.getTotalId());
                sumObj.put("fieldName",total.getTotalName());
                sumObj.put("unit",total.getUnit());
                sumObj.put("data",total.getValue());
                array.add(sumObj);
            }
        }
        return array;
    }

    /**
     * 获取基本信息
     * @param reportTempId      报表模板id
     * @param reportId          报表id
     * @param orgName           组织名称
     * @param reportTempName    报表名称
     * @param reportType        报表类型1日报表2月报表
     * @param editable          是否可以编辑
     * @return
     */
    @Override
    public JSONObject getInfo(String reportTempId,String reportId,String orgName,String reportTempName,int reportType,boolean editable) {
        Report report = jsmReportMapper.selectByPrimaryKey(reportId);
        Date date = null;
        if( report != null ){
            reportTempId = report.getReportTempId();
            orgName = report.getOrgName();
            date = report.getReportTime();
        }
        ReportTemp reportTemp = jsmReportTempMapper.queryById(reportTempId);
        if( reportTemp != null ){
            reportTemp = queryById(reportTempId);
            orgName = reportTemp.getOrgName();
            reportType = reportTemp.getReportType();
            reportTempName = reportTemp.getReportTempName();
        }
        if( date == null ){
            date = new Date();
        }
        JSONObject obj = new JSONObject();
        obj.put("editable",editable);
        obj.put("reportName",reportTempName);
        obj.put("reportType",reportType == 1?"day":"mouth");
        obj.put("orgName",orgName);
        obj.put("producePosition",report != null ? report.getProductionHorizon():"");
        obj.put("date",reportType == 1? DateUtil.DateToString(date,"yyyy-MM-dd"):DateUtil.DateToString(date,"yyyy-MM"));
        obj.put("reportType",reportType);
        obj.put("dutyOfficer",report != null ? report.getDutyPerson():"");
        obj.put("reviewer",report != null ? report.getReviewedPerson():"");
        obj.put("remark",report != null ? report.getRemark():"");
        return obj;
    }

    /**
     * 获取报表数据
     * @param reportId      报表id
     * @param remark        大事纪要
     * @return
     */
    @Override
    public JSONArray getData(String reportTempId,String reportId, String remark) {
        Date date = new Date();
        // 查询模板
        ReportTemp reportTemp = jsmReportTempMapper.queryById(reportTempId);
        int type = 1;
        // 模板为空时根据报表查询模板
        if( reportTemp == null ){
            Report report = jsmReportMapper.selectByPrimaryKey(reportId);
            // 报表不为空时设置各种参数
            if( report != null ){
                reportTemp = jsmReportTempMapper.queryById(report.getReportTempId());
                date = report.getReportTime();
                type = 2;
            }
        }
        // 获取第一列时间数据
        JSONArray data = ReportUtil.getDataArr(reportTemp.getStartHour(),reportTemp.getCycleInterval(),reportTemp.getReportType(),date);
        // 测量点信息
        List<String> apids = jsmReportTempMapper.queryApIds(reportTemp.getReportTempId());
        return formData(data,apids,remark,type);
    }

    /**
     * 通过报表模板新增或者修改页面进入
     * @param heads
     * @param startHour
     * @param cycleInterval
     * @param reportType
     * @return
     */
    @Override
    public JSONArray getData(List<ReportTempHead> heads, int startHour, int cycleInterval, int reportType) {
        // 获取第一列时间数据
        JSONArray data = ReportUtil.getDataArr(startHour,cycleInterval,reportType,new Date());
        // 测量点信息
        List<String> apids = getApids(heads);
        return formData(data,apids,"",1);
    }

    /**
     * 查询整点数据
     * @param strs      测量点
     * @param datestr   日期
     * @param timestr   整点
     * @return
     */
    @Override
    public HashMap queryPointData(List<HashMap> strs, String datestr, String timestr) {
        Map map = new HashMap<>();
        map.put("list",strs);
        map.put("datestr",datestr);
        map.put("timestr",timestr);
        return intDataSrcItemValueMapper.queryPointData(map);
    }

    /**
     * 找到某个组织下还没有关联的数据集
     *
     * @param reportTemp
     * @return
     */
    @Override
    public  Map<String,Object> queryByOrgIdWithoutAssociate(ReportTemp reportTemp) {
        Map<String,Object> result= Maps.newHashMap();
        if(Strings.isNullOrEmpty(reportTemp.getOrgId())){
            result.put("rows", Lists.newArrayList());
            result.put("total",0);
        }else{
            List<ReportTemp> reportTemps = jsmReportTempMapper.queryByOrgIdWithoutAssociate(reportTemp);
            int reportTempCount = jsmReportTempMapper.queryByOrgIdWithoutAssociateCount(reportTemp);
            result.put("rows",reportTemps==null? Lists.newArrayList():reportTemps);
            result.put("total",reportTempCount);
        }
        return result;
    }



    /**
     * 保存表头和合计
     * @param reportTemp
     * @param heads
     * @param userId
     */
    private void saveHeadsAndSums(ReportTemp reportTemp, List<ReportTempHead> heads,String userId){
        int result;
        List<ReportTempHead> sub;
        // 新增1级表头
        if( heads != null && heads.size() >0 ){
            for( ReportTempHead head:heads ){
                head.setReportTempId(reportTemp.getReportTempId());
                head.setCreateUserId(userId);
                head.setHeadId(UniqueUtil.uuid());
                result = reportTempHeadMapper.insert(head);
                sub = head.getSub();
                // 1级表头新增成功且有2级时循环保存
                if( result > 0 && sub != null && sub.size() > 0 ){
                    for(ReportTempHead subHead:sub){
                        subHead.setReportTempId(reportTemp.getReportTempId());
                        subHead.setCreateUserId(userId);
                        subHead.setParentHeadId(head.getHeadId());
                        subHead.setHeadId(UniqueUtil.uuid());
                        reportTempHeadMapper.insert(subHead);
                    }
                }
            }
        }
    }

    /**
     * 提取表头特性值
     * @param list
     * @return
     */
    public List<String> getApids(List<ReportTempHead> list){
        List<String> str = new ArrayList<>();
        List<ReportTempHead> subs;
        for( ReportTempHead head:list ){
            // 如果有二级表头且二级表头不为空,加入二级表头的测量点
                subs = head.getSub();
            if( subs != null && subs.size() > 0 ){
                for( ReportTempHead sub:subs ){
                    str.add(sub.getApId());
                }
            }else{
                // 否则加入1级表头的测量点
                str.add(head.getApId());
            }
        }
        return str;
    }

    /**
     * 组装报表列表数据
     * @param data      数据
     * @param apids     测量点
     * @param remark    大事纪要
     * @param type      类型 1：无数据，2有数据
     * @return
     */
    public JSONArray formData(JSONArray data, List<String> apids,String remark,int type){
        JSONArray array = new JSONArray();
        JSONObject obj;
        HashMap map;
        Iterator it;
        // 不为空则循环遍历
        logger.info( "数据-data:"+data.toString()+";apids:"+apids.toString()+";type="+type );
        if( data != null && data.size() > 0 ) {
            List<HashMap> list = new ArrayList<>();
            HashMap strMap;
            // 讲查询出来的apId处理一下，可以作为表头
            if( apids != null && apids.size()>0 ){
                for( String str:apids ){
                    strMap = new HashMap();
                    strMap.put("apId",str);
                    strMap.put("col",changeApId(str));
                    list.add(strMap);
                }
            }

            for(int i=0;i<data.size();i++){
                obj = data.getJSONObject(i);
                if( type == 1 ){
                    for( HashMap hashMap:list ){
                        obj.put((String)hashMap.get("col"),"");
                    }
                }else{
                    map = queryPointData(list,obj.getString("day"),obj.getString("hour"));
                    // 查询到有数据 则遍历map
                    if( map != null){
                        it = map.entrySet().iterator();
                        while (it.hasNext()){
                            Map.Entry entry = (Map.Entry) it.next();
                            obj.put((String)entry.getKey(),entry.getValue());
                        }
                    }else{
                        for( HashMap hashMap:list ){
                            obj.put((String)hashMap.get("col"),"");
                        }
                    }
                }
                // 如果是第一条数据，加入备注信息
                if( i == 0 ){
                    obj.put("event",remark+"");
                }
                array.add(obj);
            }
        }
        return array;
    }

    /**
     * 将apId转换为可用的
     * @param apId
     * @return
     */
    public String changeApId(String apId){
        if( StringUtils.isNotBlank(apId) ){
            if( apId.lastIndexOf(".") > 0 ){
                apId = "APID"+apId.substring(apId.lastIndexOf(".")+1,apId.length());
            }else if( apId.lastIndexOf("\\\\") > 0 ){
                apId = "APID"+apId.substring(apId.lastIndexOf("\\\\")+1,apId.length());
            }else{
                apId = "APID"+apId;
            }
        }
        return apId;
    }
}
